package com.specialized.orders.service.impl;

import java.util.*;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.specialized.common.core.domain.Result;
import com.specialized.common.core.utils.DateUtils;
import com.specialized.common.core.utils.MapUtil;
import com.specialized.common.security.utils.SecurityUtils;
import com.specialized.orders.common.domain.Distance;
import com.specialized.orders.common.domain.RealTime;
import com.specialized.orders.utils.DelayedQueue;
import com.specialized.system.domain.SysUser;
import com.specialized.system.model.LoginUser;
import lombok.extern.log4j.Log4j2;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.specialized.orders.mapper.RealTimeMapper;
import com.specialized.orders.service.IRealTimeService;

/**
 * 实时订单Service业务层处理
 *
 * @author djh
 * @date 2024-07-23
 */
@Log4j2
@Service
public class RealTimeServiceImpl implements IRealTimeService {


    @Autowired
    private RealTimeMapper realTimeMapper;

    /**
     * 查询实时订单
     *
     * @param realtimeId 实时订单主键
     * @return 实时订单
     */
    @Override
    public RealTime selectRealTimeByRealtimeId(Long realtimeId) {
        return realTimeMapper.selectRealTimeByRealtimeId(realtimeId);
    }

    /**
     * 查询实时订单列表
     *
     * @param realTime 实时订单
     * @return 实时订单
     */
    @Override
    public List<RealTime> selectRealTimeList(RealTime realTime) {
        return realTimeMapper.selectRealTimeList(realTime);
    }

    /**
     * 新增实时订单
     *
     * @param realTime 实时订单
     * @return 结果
     */
    @Override
    public int insertRealTime(RealTime realTime) {
        realTime.setCreateTime(DateUtils.getNowDate());
        return realTimeMapper.insertRealTime(realTime);
    }

    /**
     * 修改实时订单
     *
     * @param realTime 实时订单
     * @return 结果
     */
    @Override
    public int updateRealTime(RealTime realTime) {
        return realTimeMapper.updateRealTime(realTime);
    }

    /**
     * 批量删除实时订单
     *
     * @param realtimeIds 需要删除的实时订单主键
     * @return 结果
     */
    @Override
    public int deleteRealTimeByRealtimeIds(Long[] realtimeIds) {
        return realTimeMapper.deleteRealTimeByRealtimeIds(realtimeIds);
    }

    /**
     * 删除实时订单信息
     *
     * @param realtimeId 实时订单主键
     * @return 结果
     */
    @Override
    public int deleteRealTimeByRealtimeId(Long realtimeId) {
        return realTimeMapper.deleteRealTimeByRealtimeId(realtimeId);
    }




    /**
     * 根据地址信息获取经纬度
     * @param addr
     * @return
     */
    @Override
    public Result addAddrLongitudeLatitude(String addr) {
        String string = MapUtil.findAddr(addr);
        log.info("经纬度为:"+string);
        return Result.success(string);
    }



    /**
     * 根据经纬度计算两地点直接的距离
     */
    public static String DRIVER_URL = "https://restapi.amap.com/v3/direction/driving?";
    public static String key = "793774c415f9f7678ea8a85e54fa61b7";
    @Override
    public Distance computeDistance(String origin, String destination) {
        DRIVER_URL += "key=793774c415f9f7678ea8a85e54fa61b7"+"&extensions=all"+"&origin="+origin
                +"&destination="+destination;
        String string = HttpUtil.get(DRIVER_URL);
        log.info("两地点之间距离为:"+string);
        Distance driver = JSONObject.parseObject(string, Distance.class);
        return driver;
    }


    @Autowired
    private DelayedQueue delayedQueue;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * 实时订单
     * @param realTime
     */
    @Override
    public Result addRealTimeOrders(RealTime realTime) {
        List<RealTime> realTimeOrderstatus = realTimeMapper.findRealTimeOrder(realTime.getOrderStatus());
        for (RealTime orderstatus : realTimeOrderstatus) {
            if (orderstatus.getOrderStatus().equals(4L)) {
                //用户信息
//                LoginUser loginUser = SecurityUtils.getLoginUser();
//                SysUser sysUser = loginUser.getSysUser();
//                String phonenumber = sysUser.getPhonenumber();
                realTime.setUserId(1L);
//                realTime.setUserTel(phonenumber);
                //订单号
                String numcard = RandomUtil.randomNumbers(6);
                String string = DateUtils.dateTime();
                String ordercard = numcard + string + 1L;
                realTime.setOrderCard(ordercard);
                //根据地址计算经纬度
                Result longitudeLatitude = addAddrLongitudeLatitude(realTime.getStartPoint());
                realTime.setStartPoint(String.valueOf(longitudeLatitude));
                realTime.setDestination(String.valueOf(longitudeLatitude));
                //根据经纬度计算两点距离
//                Distance distance = computeDistance(realTime.getStartPointLongitude()+","+realTime.getStartPointLatitude(),realTime.getDestinationLongitude()+","+realTime.getDestinationLatitude());
//                List<Distance.RouteDTO.PathsDTO> paths = distance.getRoute().getPaths();
//                Integer distance1 = paths.get(0).getDistance();
//                realTime.setDistance(Long.valueOf(distance1));
//                realTime.setOrderStatus(4L);
                //异步下单
                rabbitTemplate.convertAndSend("addorder", JSONObject.toJSONString(realTime), message -> {
                    message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                    return message;
                });
                delayedQueue.sendDelayedQueue("ordersstatus", realTime, 1000 * 60);
            }
        }
        return Result.success();
    }


    @Override
    public void addRealTimeOrdersss(RealTime realTime) {
        realTimeMapper.addRealTimeOrdersss(realTime);
    }


    private static final double BASIC_FESS = 30.0; //基础费
    private static final double STARTING_PRICE = 15.0; //起步价
    private static final double TIME_FEE_MINUTE = 0.3;  //每分钟时长费
    private static final double DISTANCE_FEE_KM = 2.4; //每公里里程费
    private static final double FAR_WAY = 1.25; //远途费
    private static final double NIGHT_SERVICE  = 0.8; //夜间服务费
    private static final double TIME_PRICE  = 0.3; //元/分钟
    @Override
    public Double computeMoneyrule(RealTime realTime) {
        //23点
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.HOUR_OF_DAY,23);
        instance.set(Calendar.MINUTE,0);
        instance.set(Calendar.SECOND,0);
        Date time = instance.getTime();
        //第二天6点
        Calendar instance1 = Calendar.getInstance();
        instance1.set(Calendar.HOUR_OF_DAY,6);
        instance1.set(Calendar.DAY_OF_MONTH,(DateUtil.date().getDay()+1));
        instance1.set(Calendar.MINUTE,0);
        instance1.set(Calendar.SECOND,0);
        Date time1 = instance1.getTime();
        //判断下单时间是否是夜间
        boolean date = DateUtil.isIn(realTime.getCreateTime(), time, time1);
        log.info(date);
        //经纬度
        String start = realTime.getStartPointLongitude()+","+ realTime.getStartPointLatitude();
        String end = realTime.getDestinationLongitude()+","+realTime.getDestinationLatitude();
        Distance distance = computeDistance(start, end);
        Integer distant = (distance.getRoute().getPaths().get(0).getDistance())/1000;
        Integer distang = distant/1000;
        Integer minute = (distance.getRoute().getPaths().get(0).getDuration())/60;
        realTime.setDistance(Long.valueOf(distang));
        if(date){
            Double price = computePrice(realTime,minute);
            return price;
        }else {
            Double money = computeMoney(realTime, minute);
            return money;
        }
    }


    private Double computePrice(RealTime realTime,Integer minute) {
        double money = BASIC_FESS + STARTING_PRICE + NIGHT_SERVICE*realTime.getDistance() + TIME_PRICE*minute;
        //判断时间是否大于起步价时间
        if(minute>5){
            Integer realminute = minute-5;
            money+=(realminute*TIME_FEE_MINUTE);
        }
        Long distance = realTime.getDistance();
        if(distance>2 && distance<15){
            long reallong = distance-2;
            money+=reallong*2.4;
        }
        //判断是否远途
        if(distance>15){
            long realong = distance-15;
            money+=realong*1.25;
        }
        return money;
    }

    private Double computeMoney(RealTime realTime,Integer minute) {
        double price = BASIC_FESS + STARTING_PRICE;
        //判断时间是否大于起步价时间
        if(minute>15){
            Integer realminute = minute-5;
            price+=(realminute*TIME_FEE_MINUTE);
        }
        Long distance = realTime.getDistance();
        if(distance>2 && distance<15){
            long reallong = distance-2;
            price+=reallong*2.4;
        }
        //判断是否远途
        if(distance>15){
            long realong = distance-15;
            price+=realong*1.25;
        }
        return price;
    }





//    @Override
//    public void addRealTime(RealTime realTime) {
//        String uuid = UUID.randomUUID().toString().replace("_", "");
//        realTime.setRealtimeId(Long.valueOf(uuid));
//        realTimeMapper.addRealTime(realTime);
//    }



    @Override
    public RealTime selectRealTimeOrderCard(String orderCard) {
        RealTime realTime = realTimeMapper.selectRealTimeOrderCard(orderCard);
        return realTime;
    }



    @Override
    public void updateOrdersStatusDriver(String orderCard) {
        realTimeMapper.updateOrdersStatusDriver(orderCard);
    }







}
